package cn.jasonone.jasonfx.factory;

import java.io.File;
import java.lang.reflect.Field;
import java.util.List;

import cn.jasonone.jasonfx.annotation.FXBind;
import cn.jasonone.jasonfx.annotation.FXModel;
import cn.jasonone.jasonfx.entity.JFXBaseController;
import cn.jasonone.jasonfx.proxy.Proxy;
import cn.jasonone.jasonfx.util.AnnotationUtil;
import cn.jasonone.jasonfx.util.ClassUtil;
import cn.jasonone.jasonfx.util.ControllerUtil;
import cn.jasonone.jasonfx.util.StringUtil;
import javafx.scene.Node;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

/**
 * 模型处理工厂
 * 
 * @author Jason
 * @date: 2020-01-25 12:57
 */
@Slf4j
public class ModeFactory {
	/**
	 * ID分隔符
	 */
	public static final String ID_SEPARATOR = "$";

	/**
	 * 将模型绑定到指定控制器
	 * 
	 * @param controller 控制器
	 */
	public static void Handle(@NonNull JFXBaseController controller) {
		Class<? extends JFXBaseController> controllerType = controller.getClass();
		log.debug("绑定控制器模型:[{}]", ControllerUtil.getControllerName(controller));
		handler(controller, controller, null, controllerType);
	}

	/**
	 * 处理控制器模型
	 * 
	 * @param controller 控制器
	 * @param superObj   父实例
	 * @param prefix     前缀
	 * @param type       类型
	 */
	private static void handler(JFXBaseController controller, Object superObj, String prefix, Class<?> type) {
		List<Field> fields = ClassUtil.getFields(type,
				superObj instanceof JFXBaseController ? JFXBaseController.class : null);
		ClassUtil.clearFieldFinal(fields);
		if (prefix == null) {
			prefix = "";
		}
		for (Field field : fields) {
			// 获得字段类型
			Class<?> ftype = field.getType();
			// 检测类型是否是一个模型对象
			if (AnnotationUtil.isAnnotations(ftype, FXModel.class)) {
				if (AnnotationUtil.isAnnotations(field, FXBind.class)) {
					Object value = ClassUtil.get(field, superObj);
					if (value == null) {
						// 获取Bean
						value = BeanFactory.getBean(field.getName(), ftype);
						value = new Proxy<>(value).create();
						ClassUtil.set(field, superObj, value);
					}
					if (value != null) {
						handler(controller, value, prefix + field.getName() + ID_SEPARATOR, ftype);
					}
				}
			} else {
				Node node = null;
				if (AnnotationUtil.isAnnotations(field, FXBind.class)) {
					FXBind bind = AnnotationUtil.getAnnotation(field, FXBind.class);
					String id = bind.value();
					if (StringUtil.isEmpty(id)) {
						id = field.getName();
					}
					node = controller.lookup("#" + id);
				} else if (StringUtil.isNotEmpty(prefix)) {
					// 不是模型对象,则动态注册拦截器
					node = controller.lookup("#" + prefix + field.getName());
				}
				if (node != null) {
					log.trace("绑定控件[{}(#{})]到[{}]类的[{}]属性", node.getClass().getSimpleName(), prefix + field.getName(),
							ControllerUtil.getControllerName(controller), prefix + field.getName());
					Proxy.registerInterceptor(superObj,
							PropertyFactory.createPropertyInterceptor(superObj, field, node));
				}

			}
		}
	}
}
